/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.felinelayer.server.application;

import br.com.felinelayer.common.Message;
import br.com.felinelayer.common.Protocol;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

/**
 *
 * @author Vanius Roberto Bittencourt
 */
public class GridServer extends ComponentServer<GridServer> {
    /** Columns definitions */
    private GridColumnServer[] columns;
    /** Rows values */
    private ArrayList<ArrayList<String>> rows = new ArrayList<>();
    /** Table model listener */
    private TableModelListener tableModelEvent = new TableModelListener() {
        @Override
        public void tableChanged( TableModelEvent e ) {
            //TODO: here shoud detect when rows or column size changes
            e.getType();
        }
    };
    /** Table model */
    private TableModel tableModel = new AbstractTableModel() {
        @Override
        public int getRowCount() {
            return rows.size();
        }

        @Override
        public int getColumnCount() {
            if ( columns == null ) {
                return 0;
            }
            return columns.length;
        }

        @Override
        public Object getValueAt( int rowIndex, int columnIndex ) {
            if (rows != null) {
                return rows.get( rowIndex ).get( columnIndex );
            }
            return rowIndex + " " + columnIndex;
        }
    };

    private int getColumnCount() {
        if ( columns != null ) {
            return columns.length;
        }
        if ( tableModel != null ) {
            return tableModel.getColumnCount();
        }
        return 0;
    }

    @Override
    protected void doMessageReceived( Message message ) {
        // Event message received
        if ( message.isPropertyExists( Protocol.EVENT_NAME ) ) {
            String eventName = message.getValueByName( Protocol.EVENT_NAME );
            // Grid row count 
            if ( eventName.equals( Protocol.GRID_GET_ROW_COUNT ) ) {
                message.setValueByName( Protocol.GRID_ROW_COUNT, tableModel.getRowCount() );
            }
            // Grid column count
            if ( eventName.equals( Protocol.GRID_GET_COLUMN_COUNT ) ) {
                message.setValueByName( Protocol.GRID_COLUMN_COUNT, getColumnCount() );
            }
            // Cells values
            if ( eventName.equals( Protocol.GRID_GET_VALUES_MATRIX ) ) {
                int rowSta = message.getIntByName( Protocol.GRID_ROW_START );
                int colSta = message.getIntByName( Protocol.GRID_COLUMN_START );
                int rowEnd = message.getIntByName( Protocol.GRID_ROW_END );
                int colEnd = message.getIntByName( Protocol.GRID_COLUMN_END );
                String[] result = new String[((colEnd - colSta + 1) * (rowEnd - rowSta + 1))];
                int i = 0;
                for ( int r = rowSta; r < rowEnd + 1; r++ ) {
                    for ( int c = colSta; c < colEnd + 1; c++ ) {
                        result[i] = tableModel.getValueAt( r, c ).toString();
                        i++;
                    }
                }
                message.setValueByName( Protocol.GRID_VALUES_MATRIX, 
                        Arrays.asList( result ) );
            }
        }
    }

    public int getRowCount() {
        return tableModel.getRowCount();
    }

    public void setColumns( GridColumnServer[] columns ) {
        this.columns = columns;
        Message message = new Message( Protocol.MSG_NAME_COMPONENT_PROPERTY_CHANGE );
        ArrayList<Message> ms = new ArrayList<>();
        for ( GridColumnServer col : columns ) {
            Message m = new Message( Protocol.GRID_COLUMN );
            m.setValueByName( Protocol.GRID_COLUMN_INDEX, col.index );
            m.setValueByName( Protocol.GRID_COLUMN_TITLE, col.title );
            m.setValueByName( Protocol.GRID_COLUMN_TYPE, col.type );
            m.setValueByName( Protocol.GRID_COLUMN_ALIGMENT, col.aligment );
            ms.add( m );
        }
        message.setValueByName( Protocol.GRID_GET_COLUMNS, ms );
        sendMessage( message );
    }

    public GridServer addRow( String... columns ) {
        rows.add( new ArrayList<>( Arrays.asList( columns ) ) );
        return this;
    }

    public void setModel( TableModel tableModel ) {
        if ( this.tableModel != null ) {
            this.tableModel.removeTableModelListener( tableModelEvent );
        }
        this.tableModel = tableModel;
        if ( this.tableModel != null ) {
            this.tableModel.addTableModelListener( tableModelEvent );
        }
    }

    @Override
    public String getComponentClassName() {
        return Protocol.COMPONENT_GRID;
    }
}
